Previous: Machine-Independent Predicates, Up: Predicates

#### 14.7.2 Defining Machine-Specific Predicates

Many machines have requirements for their operands that cannot be expressed precisely using the generic predicates. You can define additional predicates using `define_predicate` and `define_special_predicate` expressions. These expressions have three operands:

- The name of the predicate, as it will be referred to in `match_operand` or `match_operator` expressions.
- An RTL expression which evaluates to true if the predicate allows the operand op, false if it does not. This expression can only use the following RTL codes:
  `MATCH_OPERAND`
    When written inside a predicate expression, a `MATCH_OPERAND` expression evaluates to true if the predicate it names would allow op. The operand number and constraint are ignored. Due to limitations in genrecog, you can only refer to generic predicates and predicates that have already been defined.
  `MATCH_CODE`
    This expression evaluates to true if op or a specified subexpression of op has one of a given list of RTX codes.

    The first operand of this expression is a string constant containing a comma-separated list of RTX code names (in lower case). These are the codes for which the `MATCH_CODE` will be true.

    The second operand is a string constant which indicates what subexpression of op to examine. If it is absent or the empty string, op itself is examined. Otherwise, the string constant must be a sequence of digits and/or lowercase letters. Each character indicates a subexpression to extract from the current expression; for the first character this is op, for the second and subsequent characters it is the result of the previous character. A digit n extracts XEXP (e, n); a letter l extracts XVECEXP (e, 0, n) where n is the alphabetic ordinal of l (0 for `a', 1 for 'b', and so on). The `MATCH_CODE` then examines the RTX code of the subexpression extracted by the complete string. It is not possible to extract components of an `rtvec` that is not at position 0 within its RTX object.

  `MATCH_TEST`
    This expression has one operand, a string constant containing a C expression. The predicate's arguments, op and mode, are available with those names in the C expression. The `MATCH_TEST` evaluates to true if the C expression evaluates to a nonzero value. `MATCH_TEST` expressions must not have side effects.
  `AND`
  `IOR`
  `NOT`
  `IF_THEN_ELSE`
    The basic MATCH_ expressions can be combined using these logical operators, which have the semantics of the C operators &&, ||, !, and ? : respectively. As in Common Lisp, you may give an `AND` or `IOR` expression an arbitrary number of arguments; this has exactly the same effect as writing a chain of two-argument `AND` or `IOR` expressions.
- An optional block of C code, which should execute return true if the predicate is found to match and return false if it does not. It must not have any side effects. The predicate arguments, op and mode, are available with those names.

  If a code block is present in a predicate definition, then the RTL expression must evaluate to true and the code block must execute return true for the predicate to allow the operand. The RTL expression is evaluated first; do not re-check anything in the code block that was checked in the RTL expression.

The program genrecog scans `define_predicate` and `define_special_predicate` expressions to determine which RTX codes are possibly allowed. You should always make this explicit in the RTL predicate expression, using `MATCH_OPERAND` and `MATCH_CODE`.

Here is an example of a simple predicate definition, from the IA64 machine description:

         ;; True if op is a SYMBOL_REF which refers to the sdata section.
         (define_predicate "small_addr_symbolic_operand"
           (and (match_code "symbol_ref")
                (match_test "SYMBOL_REF_SMALL_ADDR_P (op)")))

And here is another, showing the use of the C block.

         ;; True if op is a register operand that is (or could be) a GR reg.
         (define_predicate "gr_register_operand"
           (match_operand 0 "register_operand")
         {
           unsigned int regno;
           if (GET_CODE (op) == SUBREG)
             op = SUBREG_REG (op);

           regno = REGNO (op);
           return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
         })

Predicates written with `define_predicate` automatically include a test that mode is `VOIDmode`, or op has the same mode as mode, or op is a `CONST_INT` or `CONST_DOUBLE`. They do not check specifically for integer `CONST_DOUBLE`, nor do they test that the value of either kind of constant fits in the requested mode. This is because target-specific predicates that take constants usually have to do more stringent value checks anyway. If you need the exact same treatment of `CONST_INT` or `CONST_DOUBLE` that the generic predicates provide, use a `MATCH_OPERAND` subexpression to call `const_int_operand`, `const_double_operand`, or `immediate_operand`.

Predicates written with `define_special_predicate` do not get any automatic mode checks, and are treated as having special mode handling by genrecog.

The program genpreds is responsible for generating code to test predicates. It also writes a header file containing function declarations for all machine-specific predicates. It is not necessary to declare these predicates in cpu-protos.h.